/**
 * Copyright  (c) 2009-2013 XLab,  Org. 
 * All  rights  reserved. 
 */
package org.xlab.baseframework.aspect;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.xlab.baseframework.annotation.Loggable;
import org.xlab.baseframework.common.entity.AbstractSystemBean;
import org.xlab.baseframework.domain.ISystemUserDomain;
import org.xlab.baseframework.exception.SystemRuntimeException;
import org.xlab.baseframework.service.api.ISystemLogService;

/**
 * 为所有服务类所做的切面
 * 
 * @author MaKuBEX Email:makubexnet@gmail.com
 * @version 1.0.0 Sep 7, 2010
 * @since 1.0.0
 */
@Component
public class AspectForServices extends AbstractSystemBean {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = 6749356766957284465L;

	@Autowired(required = true)
	@Qualifier("bpf_systemLogService")
	private ISystemLogService systemLogService;

	private static final Logger log = Logger.getLogger(AspectForServices.class);

	public Object catchException(ProceedingJoinPoint pjp, Loggable loggable)
			throws Throwable {
		ISystemUserDomain loggedBy = null;
		for (Object o : pjp.getArgs()) {
			if (o != null && o.getClass().equals(ISystemUserDomain.class)) {
				loggedBy = (ISystemUserDomain) o;
			}
		}
		if (loggedBy == null) {
			log.warn("There is no ISystemUserDomain instance found! Now using system root user instance instead!");
			loggedBy = super.userService.getSystemRootUser();
		}
		try {
			String title = null;
			if (loggable.title().trim().length() != 0)
				title = loggable.title().trim();
			else
				title = pjp.toShortString();
			String desc = null;
			if (loggable.description().trim().length() != 0)
				desc = loggable.description().trim();
			else
				desc = pjp.toLongString();
			this.systemLogService.createSystemLog(title, desc,
					loggable.logLevel(), loggedBy);
			Object result = pjp.proceed();
			return result;
		} catch (SystemRuntimeException e) {
			log.error(e);
			if (loggable.value()) {
				systemLogService.createSystemLog(new SystemRuntimeException(e),
						loggable.logLevel(), loggedBy);
			}
			throw e;
		}
	}

	/**
	 * @return the systemLogService
	 */
	public ISystemLogService getSystemLogService() {
		return systemLogService;
	}

	/**
	 * @param systemLogService
	 *            the systemLogService to set
	 */
	public void setSystemLogService(ISystemLogService systemLogService) {
		this.systemLogService = systemLogService;
	}

}
